home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / Onboard / OnboardGtk.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  18.8 KB  |  573 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from xml.dom import minidom
  5. import sys
  6. import gobject
  7. gobject.threads_init()
  8. import gtk
  9. import re
  10. import string
  11. import virtkey
  12. import gconf
  13. import gettext
  14. import os.path as os
  15. import gettext
  16. from gettext import gettext as _
  17. from Onboard.Keyboard import Keyboard
  18. from KeyGtk import *
  19. from Onboard.Pane import Pane
  20. from Onboard.KbdWindow import KbdWindow
  21. from optparse import OptionParser
  22. import KeyCommon
  23. from Onboard.utils import run_script
  24. import Onboard.utils as utils
  25. app = 'onboard'
  26. gettext.textdomain(app)
  27. gettext.bindtextdomain(app)
  28. DEFAULT_FONTSIZE = 10
  29.  
  30. class OnboardGtk(object):
  31.     """
  32.     This class is a mishmash of things that I didn't have time to refactor in to seperate classes.
  33.     It needs a lot of work.
  34.     The name comes from onboards original working name of simple onscreen keyboard.  
  35.     """
  36.     
  37.     def __init__(self, main = True):
  38.         parser = OptionParser()
  39.         parser.add_option('-l', '--layout', dest = 'filename', help = 'Specify layout .sok file')
  40.         parser.add_option('-x', dest = 'x', help = 'x coord of window')
  41.         parser.add_option('-y', dest = 'y', help = 'y coord of window')
  42.         parser.add_option('-s', '--size', dest = 'size', help = 'size widthxheight')
  43.         (options, args) = parser.parse_args()
  44.         self.SOK_INSTALL_DIR = utils.get_install_dir()
  45.         if not self.SOK_INSTALL_DIR:
  46.             print 'Onboard not installed properly'
  47.             return None
  48.         sys.path.append(os.path.join(self.SOK_INSTALL_DIR, 'scripts'))
  49.         self.vk = virtkey.virtkey()
  50.         self.gconfClient = gconf.client_get_default()
  51.         self.gconfClient.add_dir('/apps/sok', gconf.CLIENT_PRELOAD_NONE)
  52.         if options.filename:
  53.             filename = options.filename
  54.         else:
  55.             filename = self.gconfClient.get_string('/apps/sok/layout_filename')
  56.         if not filename:
  57.             filename = os.path.join(self.SOK_INSTALL_DIR, 'layouts', 'Default.sok')
  58.         
  59.         if not os.path.exists(filename):
  60.             self.load_default_layout()
  61.         else:
  62.             self.load_layout(filename)
  63.         self.macros = self.gconfClient.get_list('/apps/sok/macros', gconf.VALUE_STRING)
  64.         self.window = KbdWindow(self)
  65.         self.window.set_keyboard(self.keyboard)
  66.         x = -1
  67.         y = -1
  68.         if options.x:
  69.             x = int(options.x)
  70.         
  71.         if options.y:
  72.             y = int(options.y)
  73.         
  74.         self.window.move(x, y)
  75.         if options.size:
  76.             size = options.size.split('x')
  77.             self.window.set_default_size(int(size[0]), int(size[1]))
  78.         
  79.         uiManager = gtk.UIManager()
  80.         actionGroup = gtk.ActionGroup('UIManagerExample')
  81.         actionGroup.add_actions([
  82.             ('Quit', gtk.STOCK_QUIT, _('_Quit'), None, _('Quit onBoard'), self.quit),
  83.             ('Settings', gtk.STOCK_PREFERENCES, _('_Settings'), None, _('Show settings'), self.cb_settings_item_clicked)])
  84.         uiManager.insert_action_group(actionGroup, 0)
  85.         uiManager.add_ui_from_string('<ui>\n                        <popup>\n                            <menuitem action="Settings"/>\n                            <menuitem action="Quit"/>\n                        </popup>\n                    </ui>')
  86.         trayMenu = uiManager.get_widget('/ui/popup')
  87.         
  88.         try:
  89.             self.statusIcon = gtk.status_icon_new_from_file(os.path.join(self.SOK_INSTALL_DIR, 'data', 'onboard.svg'))
  90.             self.statusIcon.connect('activate', self.cb_status_icon_clicked)
  91.             self.statusIcon.connect('popup-menu', self.cb_status_icon_menu, trayMenu)
  92.         except AttributeError:
  93.             print _('You need pygtk 2.10 or above for the system tray icon')
  94.  
  95.         self.window.hidden = False
  96.         self.window.show_all()
  97.         self.gconfClient.notify_add('/apps/sok/sizeX', self.window.do_set_size)
  98.         self.gconfClient.notify_add('/apps/sok/layout_filename', self.do_set_layout)
  99.         self.gconfClient.notify_add('/apps/sok/macros', self.do_change_macros)
  100.         self.gconfClient.notify_add('/apps/sok/scanning_interval', self.do_change_scanningInterval)
  101.         self.gconfClient.notify_add('/apps/sok/scanning', self.do_change_scanning)
  102.         self.gconfClient.notify_add('/apps/sok/trayicon', self.do_set_trayicon)
  103.         if self.gconfClient.get_bool('/apps/sok/trayicon'):
  104.             self.hide_status_icon()
  105.             self.show_status_icon()
  106.         else:
  107.             self.hide_status_icon()
  108.         if main:
  109.             gtk.main()
  110.             self.clean()
  111.         
  112.  
  113.     
  114.     def cb_settings_item_clicked(self, widget):
  115.         '''
  116.         Callback called when setting button clicked in the trayicon menu. 
  117.         '''
  118.         run_script('sokSettings', self)
  119.  
  120.     
  121.     def cb_status_icon_menu(self, status_icon, button, activate_time, trayMenu):
  122.         '''
  123.         Callback called when trayicon right clicked.  Produces menu.
  124.         '''
  125.         trayMenu.popup(None, None, gtk.status_icon_position_menu, button, activate_time, status_icon)
  126.  
  127.     
  128.     def do_set_trayicon(self, cxion_id = None, entry = None, user_data = None, thing = None):
  129.         '''
  130.         Callback called when gconf detects that the gconf key specifying 
  131.         whether the trayicon should be shown or not is changed.
  132.         '''
  133.         if self.gconfClient.get_bool('/apps/sok/trayicon'):
  134.             self.show_status_icon()
  135.         else:
  136.             self.hide_status_icon()
  137.  
  138.     
  139.     def show_status_icon(self):
  140.         '''
  141.         Shows the status icon.  When it is shown we set a wm hint so that
  142.         onboard does not appear in the taskbar.
  143.         '''
  144.         self.statusIcon.set_visible(True)
  145.         self.window.set_property('skip-taskbar-hint', True)
  146.  
  147.     
  148.     def hide_status_icon(self):
  149.         '''
  150.         The opposite of the above.
  151.         '''
  152.         self.statusIcon.set_visible(False)
  153.         self.window.set_property('skip-taskbar-hint', False)
  154.  
  155.     
  156.     def cb_status_icon_clicked(self, widget):
  157.         '''
  158.         Callback called when trayicon clicked.
  159.         Toggles whether onboard window visibile or not.
  160.  
  161.         TODO would be nice if appeared to iconify to taskbar
  162.         '''
  163.         if self.window.hidden:
  164.             self.window.deiconify()
  165.             self.window.hidden = False
  166.         else:
  167.             self.window.iconify()
  168.             self.window.hidden = True
  169.  
  170.     
  171.     def unstick(self):
  172.         for key in self.keyboard.basePane.keys.values():
  173.             if key.on:
  174.                 self.keyboard.release_key(key)
  175.                 continue
  176.         
  177.  
  178.     
  179.     def clean(self):
  180.         self.unstick()
  181.         self.window.hide()
  182.  
  183.     
  184.     def quit(self, widget = None):
  185.         self.clean()
  186.         gtk.main_quit()
  187.  
  188.     
  189.     def do_change_scanning(self, cxion_id, entry, user_data, thing):
  190.         self.keyboard.scanning = self.gconfClient.get_bool('/apps/sok/scanning')
  191.         self.keyboard.reset_scan()
  192.  
  193.     
  194.     def do_change_scanningInterval(self, cxion_id, entry, user_data, thing):
  195.         self.keyboard.scanningInterval = self.gconfClient.get_int('/apps/sok/scanningInterval')
  196.  
  197.     
  198.     def do_change_macros(self, client, cxion_id, entry, user_data):
  199.         self.macros = self.gconfClient.get_list('/apps/sok/macros', gconf.VALUE_STRING)
  200.  
  201.     
  202.     def do_set_layout(self, client, cxion_id, entry, user_data):
  203.         self.unstick()
  204.         filename = self.gconfClient.get_string('/apps/sok/layout_filename')
  205.         if os.path.exists(filename):
  206.             self.load_layout(filename)
  207.             self.window.set_keyboard(self.keyboard)
  208.         else:
  209.             self.load_default_layout()
  210.         self.window.set_keyboard(self.keyboard)
  211.  
  212.     
  213.     def hexstring_to_float(self, hexString):
  214.         return float(string.atoi(hexString, 16))
  215.  
  216.     
  217.     def get_sections_keys(self, section, keys, pane, xOffset, yOffset):
  218.         '''gets keys for a specified sections from the XServer.'''
  219.         rows = self.vk.layout_get_keys(section)
  220.         for row in rows:
  221.             for key in row:
  222.                 shape = key['shape']
  223.                 name = key['name'].strip(chr(0))
  224.                 if name in utils.modDic:
  225.                     nkey = RectKey(pane, float(shape[0] + xOffset), float(shape[1] + yOffset), float(shape[2]), float(shape[3]), (0.95, 0.9, 0.85, 1))
  226.                     props = utils.modDic[name]
  227.                     action = props[1]
  228.                     action_type = KeyCommon.MODIFIER_ACTION
  229.                     labels = (props[0], '', '', '', '')
  230.                     sticky = True
  231.                 else:
  232.                     action = key['keycode']
  233.                     action_type = KeyCommon.KEYCODE_ACTION
  234.                     if name in utils.otherDic:
  235.                         nkey = RectKey(pane, float(shape[0] + xOffset), float(shape[1] + yOffset), float(shape[2]), float(shape[3]), (0.85, 0.8, 0.65, 1))
  236.                         labels = (utils.otherDic[name], '', '', '', '')
  237.                     else:
  238.                         nkey = RectKey(pane, float(shape[0] + xOffset), float(shape[1] + yOffset), float(shape[2]), float(shape[3]), (0.9, 0.85, 0.7, 1))
  239.                         labDic = key['labels']
  240.                         labels = (labDic[0], labDic[2], labDic[1], labDic[3], labDic[4])
  241.                     sticky = False
  242.                 nkey.setProperties(action_type, action, labels, sticky, 0, 0)
  243.                 keys[name] = nkey
  244.             
  245.         
  246.  
  247.     
  248.     def load_default_layout(self):
  249.         self.keyboard = Keyboard(self)
  250.         panes = []
  251.         sizeA = self.vk.layout_get_section_size('Alpha')
  252.         sizeK = self.vk.layout_get_section_size('Keypad')
  253.         sizeE = self.vk.layout_get_section_size('Editing')
  254.         sizeF = (294, 94)
  255.         listX = [
  256.             sizeA[0],
  257.             sizeE[0] + sizeK[0] + 20 + 125,
  258.             sizeF[0]]
  259.         listY = [
  260.             sizeA[1] + 1,
  261.             sizeE[1] + 3,
  262.             sizeK[1] + 3,
  263.             64,
  264.             sizeF[1]]
  265.         listX.sort()
  266.         listY.sort()
  267.         sizeX = listX[len(listX) - 1]
  268.         sizeY = listY[len(listY) - 1]
  269.         keys = { }
  270.         pane = Pane(self.keyboard, 'Alpha', keys, None, float(sizeX), float(sizeY), [
  271.             0,
  272.             0,
  273.             0,
  274.             0.3], DEFAULT_FONTSIZE)
  275.         panes.append(pane)
  276.         self.get_sections_keys('Alpha', keys, pane, 0, 0)
  277.         keys = { }
  278.         pane = Pane(self.keyboard, 'Editing', keys, None, float(sizeX), float(sizeY), [
  279.             0.3,
  280.             0.3,
  281.             0.7,
  282.             0.3], DEFAULT_FONTSIZE)
  283.         panes.append(pane)
  284.         self.get_sections_keys('Editing', keys, pane, 0, 2)
  285.         self.get_sections_keys('Keypad', keys, pane, sizeE[0] + 20, 2)
  286.         for r in range(3):
  287.             for c in range(3):
  288.                 n = c + r * 3
  289.                 mkey = RectKey(pane, sizeE[0] + sizeK[0] + 45 + c * 38, 7 + r * 28, 33, 24, (0.5, 0.5, 0.8, 1))
  290.                 mkey.setProperties(KeyCommon.MACRO_ACTION, str(n), (_('Snippet\n%d') % n, '', '', '', ''), False, 0, 0)
  291.                 keys['m%d' % n] = mkey
  292.             
  293.         
  294.         keys = { }
  295.         pane = Pane(self.keyboard, 'Functions', keys, None, float(sizeX), float(sizeY), [
  296.             0.6,
  297.             0.3,
  298.             0.7,
  299.             0.3], DEFAULT_FONTSIZE)
  300.         panes.append(pane)
  301.         y = 0
  302.         for n in range(len(utils.funcKeys)):
  303.             if n >= 8:
  304.                 y = 27
  305.                 m = n - 8
  306.             else:
  307.                 m = n
  308.             fkey = RectKey(pane, 5 + m * 30, 5 + y, 25, 24, (0.5, 0.5, 0.8, 1))
  309.             fkey.setProperties(KeyCommon.KEYSYM_ACTION, utils.funcKeys[n][1], (utils.funcKeys[n][0], '', '', '', ''), False, 0, 0)
  310.             keys[utils.funcKeys[n][0]] = fkey
  311.         
  312.         settingsKey = RectKey(pane, 5, 61, 60, 30, (0.95, 0.5, 0.5, 1))
  313.         settingsKey.setProperties(KeyCommon.SCRIPT_ACTION, 'sokSettings', (_('Settings'), '', '', '', ''), False, 0, 0)
  314.         keys['settings'] = settingsKey
  315.         switchingKey = RectKey(pane, 70, 61, 60, 30, (0.95, 0.5, 0.5, 1))
  316.         switchingKey.setProperties(KeyCommon.SCRIPT_ACTION, 'switchButtons', (_('Switch\nButtons'), '', '', '', ''), False, 0, 0)
  317.         keys['switchButtons'] = switchingKey
  318.         basePane = panes[0]
  319.         otherPanes = panes[1:]
  320.         self.keyboard.set_basePane(basePane)
  321.         for pane in otherPanes:
  322.             self.keyboard.add_pane(pane)
  323.         
  324.  
  325.     
  326.     def load_keys(self, doc, keys):
  327.         for key in doc.getElementsByTagName('key'):
  328.             
  329.             try:
  330.                 if key.attributes['id'].value in keys:
  331.                     action = None
  332.                     action_type = None
  333.                     if key.hasAttribute('char'):
  334.                         action = key.attributes['char'].value
  335.                         action_type = KeyCommon.CHAR_ACTION
  336.                     elif key.hasAttribute('keysym'):
  337.                         value = key.attributes['keysym'].value
  338.                         action_type = KeyCommon.KEYSYM_ACTION
  339.                         if value[1] == 'x':
  340.                             action = string.atoi(value, 16)
  341.                         else:
  342.                             action = string.atoi(value, 10)
  343.                     elif key.hasAttribute('press'):
  344.                         action = key.attributes['char'].value
  345.                         action_type = KeyCommon.CHAR_ACTION
  346.                     elif key.hasAttribute('modifier'):
  347.                         
  348.                         try:
  349.                             action = utils.modifiers[key.attributes['modifier'].value]
  350.                             action_type = KeyCommon.MODIFIER_ACTION
  351.                         except KeyError:
  352.                             strerror = None
  353.                             print "Can't find modifier " + str(strerror)
  354.                         except:
  355.                             None<EXCEPTION MATCH>KeyError
  356.                         
  357.  
  358.                     None<EXCEPTION MATCH>KeyError
  359.                     if key.hasAttribute('macro'):
  360.                         action = key.attributes['macro'].value
  361.                         action_type = KeyCommon.MACRO_ACTION
  362.                     elif key.hasAttribute('script'):
  363.                         action = key.attributes['script'].value
  364.                         action_type = KeyCommon.SCRIPT_ACTION
  365.                     elif key.hasAttribute('keycode'):
  366.                         action = string.atoi(key.attributes['keycode'].value)
  367.                         action_type = KeyCommon.KEYCODE_ACTION
  368.                     
  369.                     labels = [
  370.                         '',
  371.                         '',
  372.                         '',
  373.                         '',
  374.                         '']
  375.                     if key.hasAttribute('label'):
  376.                         labels[0] = key.attributes['label'].value
  377.                         if key.hasAttribute('cap_label'):
  378.                             labels[1] = key.attributes['cap_label'].value
  379.                         
  380.                         if key.hasAttribute('shift_label'):
  381.                             labels[2] = key.attributes['shift_label'].value
  382.                         
  383.                         if key.hasAttribute('altgr_label'):
  384.                             labels[3] = key.attributes['altgr_label'].value
  385.                         
  386.                         if key.hasAttribute('altgrNshift_label'):
  387.                             labels[4] = key.attributes['altgrNshift_label'].value
  388.                         
  389.                     elif action_type == KeyCommon.KEYCODE_ACTION:
  390.                         labDic = self.vk.labels_from_keycode(action)
  391.                         labels = (labDic[0], labDic[2], labDic[1], labDic[3], labDic[4])
  392.                     
  393.                     if key.hasAttribute('font_offset_x'):
  394.                         offsetX = float(key.attributes['font_offset_x'].value)
  395.                     else:
  396.                         offsetX = 0
  397.                     if key.hasAttribute('font_offset_y'):
  398.                         offsetY = float(key.attributes['font_offset_y'].value)
  399.                     else:
  400.                         offsetY = 0
  401.                     stickyString = key.attributes['sticky'].value
  402.                     if stickyString == 'true':
  403.                         sticky = True
  404.                     else:
  405.                         sticky = False
  406.                     keys[key.attributes['id'].value].setProperties(action_type, action, labels, sticky, offsetX, offsetY)
  407.             continue
  408.             except KeyError:
  409.                 strerror = None
  410.                 print 'key missing id: ' + str(strerror)
  411.                 continue
  412.             
  413.  
  414.         
  415.  
  416.     
  417.     def parse_path(self, path, pane):
  418.         id = path.attributes['id'].value
  419.         styleString = path.attributes['style'].value
  420.         result = re.search('(fill:#\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?;)', styleString).groups()[0]
  421.         rgba = (self.hexstring_to_float(result[6:8]) / 255, self.hexstring_to_float(result[8:10]) / 255, self.hexstring_to_float(result[10:12]) / 255, 1)
  422.         dList = path.attributes['d'].value.split(' ')
  423.         dList = dList[1:-2]
  424.         coordList = []
  425.         transformMatrix = None
  426.         if path.hasAttribute('transform'):
  427.             transform = path.attributes['transform'].value
  428.             if transform.startswith('matrix'):
  429.                 transformCoords = map(float, transform[7:-1].split(','))
  430.                 transformMatrix = ((transformCoords[0], transformCoords[2], transformCoords[4]), (transformCoords[1], transformCoords[3], transformCoords[5]), (0, 0, 1))
  431.             elif transform.startswith('translate'):
  432.                 transformCoords = map(float, transform[10:-1].split(','))
  433.                 transformMatrix = ((1, 0, transformCoords[0]), (0, 1, transformCoords[1]), (0, 0, 1))
  434.             else:
  435.                 print 'Warning: Unhandled transform ' + transform
  436.         
  437.         xTotal = 0
  438.         yTotal = 0
  439.         numCoords = 0
  440.         for d in dList:
  441.             l = d.split(',')
  442.             if len(l) == 1:
  443.                 coordList.append(l)
  444.                 continue
  445.             numCoords = numCoords + 1
  446.             l = map(float, l)
  447.             if transformMatrix:
  448.                 l = utils.matmult(transformMatrix, l + [
  449.                     1])[:-1]
  450.             
  451.             xTotal = xTotal + l[0]
  452.             yTotal = yTotal + l[1]
  453.             coordList.append(l[0])
  454.             coordList.append(l[1])
  455.         
  456.         fontCoord = (xTotal / numCoords, yTotal / numCoords)
  457.         return LineKey(pane, coordList, fontCoord, rgba)
  458.  
  459.     
  460.     def load_layout(self, kblang):
  461.         self.keyboard = Keyboard(self)
  462.         scanning = self.gconfClient.get_bool('/apps/sok/scanning')
  463.         if scanning:
  464.             self.keyboard.scanning = scanning
  465.             self.keyboard.reset_scan()
  466.         else:
  467.             self.keyboard.scanning = False
  468.         scanningInterval = self.gconfClient.get_int('/apps/sok/scanning_interval')
  469.         if scanningInterval:
  470.             self.keyboard.scanningInterval = scanningInterval
  471.         else:
  472.             self.gconfClient.set_int('/apps/sok/scanning_interval', 750)
  473.         kbfolder = os.path.dirname(kblang)
  474.         f = open(kblang)
  475.         langdoc = minidom.parse(f).documentElement
  476.         f.close()
  477.         panes = []
  478.         for paneXML in langdoc.getElementsByTagName('pane'):
  479.             
  480.             try:
  481.                 path = '%s/%s' % (kbfolder, paneXML.attributes['filename'].value)
  482.                 f = open(path)
  483.                 
  484.                 try:
  485.                     svgdoc = minidom.parse(f).documentElement
  486.                     keys = { }
  487.                     
  488.                     try:
  489.                         viewPortSizeX = float(svgdoc.attributes['width'].value)
  490.                         viewPortSizeY = float(svgdoc.attributes['height'].value)
  491.                     except ValueError:
  492.                         print 'Units for canvas height and width must be px.  In the svg file this corresponds with having no units after the height and width'
  493.  
  494.                     paneBackground = [
  495.                         0,
  496.                         0,
  497.                         0,
  498.                         0]
  499.                     if paneXML.hasAttribute('backgroundRed'):
  500.                         paneBackground[0] = paneXML.attributes['backgroundRed'].value
  501.                     
  502.                     if paneXML.hasAttribute('backgroundGreen'):
  503.                         paneBackground[1] = paneXML.attributes['backgroundGreen'].value
  504.                     
  505.                     if paneXML.hasAttribute('backgroundBlue'):
  506.                         paneBackground[2] = paneXML.attributes['backgroundBlue'].value
  507.                     
  508.                     if paneXML.hasAttribute('backgroundAlpha'):
  509.                         paneBackground[3] = paneXML.attributes['backgroundAlpha'].value
  510.                     
  511.                     columns = []
  512.                     if paneXML.hasAttribute('font'):
  513.                         fontSize = string.atoi(paneXML.attributes['font'].value)
  514.                     else:
  515.                         fontSize = DEFAULT_FONTSIZE
  516.                     pane = Pane(self.keyboard, paneXML.attributes['id'].value, keys, columns, viewPortSizeX, viewPortSizeY, paneBackground, fontSize)
  517.                     for rect in svgdoc.getElementsByTagName('rect'):
  518.                         id = rect.attributes['id'].value
  519.                         styleString = rect.attributes['style'].value
  520.                         result = re.search('(fill:#\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?\\d?\\D?;)', styleString).groups()[0]
  521.                         rgba = [
  522.                             self.hexstring_to_float(result[6:8]) / 255,
  523.                             self.hexstring_to_float(result[8:10]) / 255,
  524.                             self.hexstring_to_float(result[10:12]) / 255,
  525.                             1]
  526.                         keys[id] = RectKey(pane, float(rect.attributes['x'].value), float(rect.attributes['y'].value), float(rect.attributes['width'].value), float(rect.attributes['height'].value), rgba)
  527.                     
  528.                     for path in svgdoc.getElementsByTagName('path'):
  529.                         id = path.attributes['id'].value
  530.                         keys[id] = self.parse_path(path, pane)
  531.                     
  532.                     svgdoc.unlink()
  533.                     self.load_keys(langdoc, keys)
  534.                     
  535.                     try:
  536.                         for columnXML in paneXML.getElementsByTagName('column'):
  537.                             column = []
  538.                             columns.append(column)
  539.                             for scanKey in columnXML.getElementsByTagName('scankey'):
  540.                                 column.append(keys[scanKey.attributes['id'].value])
  541.                             
  542.                     except KeyError:
  543.                         strerror = None
  544.                         print 'require %s key, appears in scanning only' % strerror
  545.  
  546.                     panes.append(pane)
  547.                 except KeyError:
  548.                     strerror = None
  549.                     print _('require %s') % strerror
  550.  
  551.                 f.close()
  552.             continue
  553.             except KeyError:
  554.                 print _('require filename in pane')
  555.                 continue
  556.             
  557.  
  558.         
  559.         langdoc.unlink()
  560.         basePane = panes[0]
  561.         otherPanes = panes[1:]
  562.         self.keyboard.set_basePane(basePane)
  563.         for pane in otherPanes:
  564.             self.keyboard.add_pane(pane)
  565.         
  566.  
  567.  
  568. if __name__ == '__main__':
  569.     s = Sok()
  570.     gtk.main()
  571.     s.clean()
  572.  
  573.